/*!
 * Test plugin for Editor.md
 *
 * @file        test-plugin.js
 * @author      pandao
 * @version     1.2.0
 * @updateTime  2015-03-07
 * {@link       https://github.com/pandao/editor.md}
 * @license     MIT
 */

(function() {

    var factory = function(exports) {
        var $ = jQuery; // if using module loader(Require.js/Sea.js).
        var pluginName = "7dtimeTable";
        var timeRange = {min:9*60, max:18*60};//开始时间和结束时间

        // exports.fn.testMind = function(p1, p2) {
        //     console.log("testMind");
        // }

        $.fn.draw7dtimeTable = function() {
            try {
                var parsed = JSON.parse($(this).text());
            } catch (err) {
                console.log("Woops! Error parsing", err);
                return;
            }


            var html = new drawFragmentTable(new fragment(parsed));


            this.empty().append(html);
            return html;

        };


        //组合成碎片图数组并返回
        var fragment = function(data) {
            var fragmentData = new Array(1440);

            //获取清单标签
            this.getTag = function(tags) {
                var tag = '';
                var tagArr = ['critical', 'high', 'low', 'minor', 'life'];
                for (var i = 0; i < tagArr.length; i++) {
                    if (tags[tagArr[i]] !== undefined)
                        return tagArr[i];
                }

            }
            //一个任务会有多次暂停情况，将一个任务分解为全部相连的小任务
            this.cutItems = function(tags) {
                var started = tags['started'],
                    done = tags['done']?tags['done']:tags['cancelled'];
                var toggle = tags['toggle'];
                let toggleArr = [];
                if (toggle) {
                    //替换、切割
                    toggle = toggle.replace(/\ (\d{2}-\d{2}-\d{2})/g, ' 20$1').trim();
                    toggleArr = toggle.replace(/\ (\d{4}-\d{2}-\d{2})/g, '|$1').split('|');
                    //排序

                    for (let i = 0; i < toggleArr.length; i++) {
                        toggleArr[i] = moment(toggleArr[i]).format('X');
                    }
                    toggleArr.sort();
                    if (toggleArr.length % 2 != 0 && toggleArr.length > 1) {
                        toggleArr.splice(toggleArr.length - 1, 1);
                    }
                    for (let i = 0; i < toggleArr.length; i++) {
                        toggleArr[i] = moment.unix(toggleArr[i]).format('YYYY-MM-DD HH:mm');
                    }
                }
                var timeGroup = [started, ...toggleArr, done];
                for (let i = 0; i < timeGroup.length; i += 2) {
                    tags['started'] = timeGroup[i];
                    tags['done'] = timeGroup[i + 1];
                    this.fillItems(tags);
                }


            }
            //填充多个小碎片
            this.fillItems = function(tags) {
                if(!(tags['started']&&tags['done'])) return ;
                var started = tags['started'],
                    done = tags['done'];
                var startItemKey = this.getIndex(started);
                var endItemKey = this.getIndex(done);

                for (var ItemKey = startItemKey; ItemKey <= endItemKey; ItemKey++) {
                    fragmentData[ItemKey] = this.fillItem(fragmentData[ItemKey], ItemKey, this.getTag(tags));
                }
            }

            //填充每个小碎片/按分钟/标签/是否重复填充
            this.fillItem = function(item, index, tag) {
                if(item==undefined) item = {};
                if (item[tag] == undefined){
                    item[tag] = (Object.keys(item).length===0)?0:1;
                } else {
                    item[tag] += 1;
                }                    
                return item;
            };

            //根据时间返回对应数组下标
            this.getIndex = function(time) {
                var h = moment(time).hour();
                var m = moment(time).minute();
                var index = h * 60 + m ;
                return index;
            }

            //今日开始时间
            this.minTime = function(tags){
                var timeArr = [];
                if(tags['started'])     timeArr.push(this.getIndex(tags['started']));
                if(tags['done'])        timeArr.push(this.getIndex(tags['done']));
                if(tags['cancelled'])   timeArr.push(this.getIndex(tags['cancelled']));
                if(timeArr.length == 0) return;

                timeRange.min = Math.min(timeRange.min, ...timeArr);
                return false;
            }

            //结束时间
            this.maxTime = function(tags){
                var timeArr = [];
                if(tags['started'])     timeArr.push(this.getIndex(tags['started']));
                if(tags['done'])        timeArr.push(this.getIndex(tags['done']));
                if(tags['cancelled'])   timeArr.push(this.getIndex(tags['cancelled']));
                if(timeArr.length == 0) return;

                timeRange.max = Math.max(timeRange.max, ...timeArr);
                return false;
            }

            for (tskey in data) {
                var tasks = data[tskey];
                for (tkey in tasks) {
                    var tags = tasks[tkey];
                    this.minTime(tags);
                    this.maxTime(tags);

                    if (!(tags['started'] && (tags['done'] || tags['toggle'] || tags['cancelled']))) {
                        continue;
                    }
                    this.cutItems(tags);
                }
            }

            return fragmentData;

        };


        //画出碎片图表格
        var drawFragmentTable = function(fragmentData) {
            var FLAG_SYSTEM = ["critical", "high", "low", "minor", "life"];
            


            //获取指定时段内指定标签的用时
            this.statisTimes = function(tag, start, end){
                var fold = 0, alone = 0;
                for(var i=start; i<end; i++){
                    if(! (fragmentData[i] && fragmentData[i][tag]!=undefined)) {
                        continue;
                    }
                    if(FLAG_SYSTEM.some(key=>{
                        return tag!="critical" && ((key != tag && fragmentData[i][key]!=undefined) || (key == tag && fragmentData[i][key]>0));
                    })){
                        fold ++ ;
                    }else{
                        alone ++;
                    }
                }
                //return [this.formatTime(fold), this.formatTime(alone)]; //单独时间 + 重叠时间
                return [alone ,fold];
            };

            

            //格式化时间
            this.formatTime = function(time){
                //return (time>60? Math.floor(time/60) + 'h':'') + ((time%60!=0||time==0)?time%60 + 'm':'');
                let h = (time>60? Math.floor(time/60) + ':':'');
                let m = time+'m';
                if(time>60){
                    m = ('00'+((time%60!=0||time==0)?time%60 + '':''));
                    m = m.substr(m.length-2);
                }
                return h + m ;
            };

            //用时
            this.solidTimes = function(start, end){
                var time = 0;
                for(var i=start; i<end; i++){
                    if(FLAG_SYSTEM.some(key=>{
                        return fragmentData[i] && fragmentData[i][key] != undefined;
                    })){
                        time ++ ;
                    }
                }
                return time;
            };

            //浪费
            this.waste = function(solidTimes, totalTimes){
                var wasteTimes = totalTimes - solidTimes;
                var rate = Math.round(wasteTimes/totalTimes*100);//.toFixed(2);
                return rate + '%('+this.formatTime(wasteTimes)+')';
            };
            var slots = [
                        {h:'早晨',r:[timeRange.min, 9*60]}, 
                        {h:'上班',  r:[9*60, 18*60]}, 
                        {h:'晚上',  r:[18*60, timeRange.max]}
                    ];
            var tables = [];
            var flag_keys = ['紧重','重要','紧急','不重要','生活'];
            var totalRow = {'时段':'总计', '使用':0, '总共':0, };
            for(var i=0; i<slots.length; i++){
                var table = {};
                var slot = slots[i];
                var start = slot['r'][0], end = slot['r'][1];
                var totalTimes =  end - start;
                var solidTimes = this.solidTimes(slot['r'][0], slot['r'][1]);
                table['时段']     = slot['h'];
                table['浪费']     = this.waste(solidTimes, totalTimes);
                table['总共']     = this.formatTime(totalTimes);
                table['使用']   = this.formatTime(solidTimes);

                totalRow['使用'] += solidTimes;
                totalRow['总共'] += totalTimes;
                
                FLAG_SYSTEM.forEach((item, index)=>{
                    table[flag_keys[index]] = this.statisTimes(item, start, end);
                    if(i == 0){
                        totalRow[flag_keys[index]] = [0, 0];
                    }
                    totalRow[flag_keys[index]]  = [ totalRow[flag_keys[index]][0] + table[flag_keys[index]][0], totalRow[flag_keys[index]][1] + table[flag_keys[index]][1] ];
                });

                tables.push(table);
            }
            totalRow['浪费']     = this.waste(totalRow['使用'], totalRow['总共']);
            totalRow['总共']     = this.formatTime(totalRow['总共']);
            totalRow['使用']   = this.formatTime(totalRow['使用']);
            tables.push(totalRow);

            //
            var html = $('<div class="fragmentTable"></div>');
            var columns = ['时段','浪费','总共','使用','紧重','重要','紧急','不重要','生活'];
            var tableObj = $('<table></table>');
            
            tables.forEach((table, index)=>{
                var tr = $('<tr></tr>');
                if(index == 0){
                    var thead = $('<tr></tr>');
                    columns.forEach(col=>{
                        thead.append('<th>'+col+'</th>');
                    });
                    tableObj.append(thead);
                }

                columns.forEach((col, key)=>{
                    var td = table[col];
                    if(flag_keys.indexOf(col) >= 0 && td.length==2){
                        
                        td = [this.formatTime(td[0]),this.formatTime(td[1])];
                        if(td[1] == '0m' || td[1] == '1m'){td.splice(1,1);}
                        td = td.join('+');
                        
                    }
                    tr.append('<td>'+td+'</td>');
                });
                tableObj.append(tr);
                
            });

            html.append(tableObj);

            return html;

        }



    };

    // CommonJS/Node.js
    if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
        module.exports = factory;
    } else if (typeof define === "function") // AMD/CMD/Sea.js
    {
        if (define.amd) { // for Require.js

            define(["editormd"], function(editormd) {
                factory(editormd);
            });
        } else { // for Sea.js
            define(function(require) {
                var editormd = require("./../../editormd");
                factory(editormd);
            });
        }
    } else {
        factory(window.editormd);
    }

})();